from typing import Mapping
import redis
from random import choice


MAX_SCORE = 100
MIN_SCORE = 0
INITIAL_SCORE = 10
REDIS_HOST = 'localhost'
REDIS_PORT = 6379
REDIS_PASSWORD = None
REDIS_KEY = 'proxies'
db = 2


# 自定义异常类
class PoolEmptyError(Exception):
    def __str__(self):
        return repr('No Proxy In Proxypool')

class RedisClient(object):
    def __init__(self,host=REDIS_HOST,port=REDIS_PORT,password=REDIS_PASSWORD,db=db):
        self.db = redis.StrictRedis(host=host,port=port,password=password,decode_responses=True,db=db)

    def add(self,proxy,score=INITIAL_SCORE):
        if not self.db.zscore(REDIS_KEY,proxy): # zscore:返回有序集中，成员的分数值
            return self.db.zadd(REDIS_KEY,{proxy:score})
    
    def random(self):
        result = self.db.zrangebyscore(REDIS_KEY,MAX_SCORE,MAX_SCORE) # 返回REDIS_KEY中范围在(MAX_SCORE,MAX_SCORE)
        if len(result):
            return choice(result)
        else:
            result = self.db.zrevrange(REDIS_KEY, 0, 100) # 返回REDIS_KEY中前100名
            if len(result):
                return choice(result)
            else:
                raise PoolEmptyError

    def decrease(self, proxy):
        score = self.db.zscore(REDIS_KEY,proxy)
        if score and score > MIN_SCORE:
            print('代理',proxy,'当前分数',score,'减1')
            return self.db.zincrby(REDIS_KEY, -1, proxy) # 键为REDIS_KEY中的proxy的score减1
        else:
            print('代理',proxy,'当前分数',score,'移除')
            return self.db.zrem(REDIS_KEY, proxy) # 删除REDIS_KEY 中的proxy

    def exists(self, proxy):
        return not self.db.zscore(REDIS_KEY, proxy) == None

    def max(self, proxy):
        print('代理',proxy, '可用，设置为', MAX_SCORE)
        return self.db.zadd(REDIS_KEY, MAX_SCORE, proxy)

    def count(self):
        return self.db.zcard(REDIS_KEY) # 向REDIS_KEY中添加元素

    def all(self):
        return self.db.zrangebyscore(REDIS_KEY, MIN_SCORE, MAX_SCORE)

    
if __name__ == '__main__':
    conn = RedisClient()
    result = conn.random()
    print(result)